package com.hxzy.common.exsyexcel;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.hxzy.common.annotates.DictTypeProperty;
import com.hxzy.common.enums.DictTypeEnum;
import com.hxzy.common.exception.ServiceStringException;
import com.hxzy.controller.admin.dict.resp.DictDataResp;
import com.hxzy.service.SysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * excel数据字典转换器
 */
public class DictDataConvert implements Converter<String> {


    @Override
    public Class<?> supportJavaTypeKey() {
        return  String.class;
    }

    /**
     * 把数据库转换并写入到excel单元格中
     * @param value               Java Data.NotNull.   数据库值
     * @param contentProperty     Content property.Nullable.
     * @param globalConfiguration Global configuration.NotNull.
     * @return
     * @throws Exception
     */
    @Override
    public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
        //1、获取当前字段
        Field field = contentProperty.getField();

        //2、获取字段上面是否拥有自定义注解
        DictTypeProperty declaredAnnotation = field.getDeclaredAnnotation(DictTypeProperty.class);

        //没有写注解
        if(Objects.isNull(declaredAnnotation)){
            throw new ServiceStringException(field.getName()+",字段上面必须要加 @DictTypeProperty注解");
        }

        DictTypeEnum dictTypeEnum = declaredAnnotation.value();

        //必须获取 Spring   BeanFactory接口 --> ApplicationContext-->ClassPathXmlApplicationContext  AnnoationApplicationContext
        // Spring生命周期（接口  ，注解）  BeanFactoryPostProcessor  获取 ApplicationContext(获取Spring容器管理的类)

        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        SysDictDataService sysDictDataService = applicationContext.getBean("sysDictDataServiceImpl", SysDictDataService.class);
        String[] dictType={dictTypeEnum.getName()};

        Map<String, List<DictDataResp>> stringListMap = sysDictDataService.searchByDictTypes(dictType);
        if(stringListMap.isEmpty()){
            throw new ServiceStringException(StrUtil.format("{}字段上面必须要加 @DictTypeProperty({})值查询不到",field.getName(),dictTypeEnum.getName()));
        }

        List<DictDataResp> dataRespList = stringListMap.get(dictTypeEnum.getName());
        //过滤集合中满足条件的对象
        Optional<DictDataResp> first = dataRespList.stream().filter(p -> p.getDictValue().equals(value)).findFirst();
        //有值
        return first.map(dictDataResp -> new WriteCellData<>(dictDataResp.getDictLabel())).orElseGet(() -> new WriteCellData<>(value));
    }
}
